package com.onion.utils.http;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.http.HttpStatus.SC_OK;

public class HttpResponseFuture implements FutureCallback<HttpResponse> {

    private static Logger logger = LoggerFactory.getLogger(HttpResponseFuture.class);

    //完成标志：0-新创建；1-请求完成；2-请求异常; 3-请求取消
    private HttpUriRequest request;
    private HttpCallback callback;
    private String charset;
    private boolean needHeader = false;
    private int finished = 0;
    private String errmsg;

    public HttpResponseFuture(HttpUriRequest request, HttpCallback callback){
        this(request, callback, "UTF-8");
    }

    public HttpResponseFuture(HttpUriRequest request, HttpCallback callback, String charset){
        this(request, callback, charset, false);
    }

    public HttpResponseFuture(HttpUriRequest request, HttpCallback callback, boolean needHeader){
        this(request, callback, "UTF-8", false);
    }

    public HttpResponseFuture(HttpUriRequest request, HttpCallback callback, String charset, boolean needHeader){
        this.request = request;
        this.callback = callback;
        this.charset = StringUtils.isNotBlank(charset) ? charset : "UTF-8";
        this.needHeader = needHeader;
    }

    @Override
    public void completed(HttpResponse response) {
        HttpResult<String> httpResult = new HttpResult<>();
        httpResult.setCode(response.getStatusLine().getStatusCode());
        if(needHeader){
            for(Header header : response.getAllHeaders()){
                httpResult.addHeader(header.getName(), header.getValue());
            }
        }
        try{
            httpResult.setBody(EntityUtils.toString(response.getEntity(), charset));
            this.finished = response.getStatusLine().getStatusCode()==SC_OK ? 1 : 2;
            if(finished == 1){
                this.callback.completed(request, httpResult);
            }else {
                this.callback.failed(request, httpResult, null);
            }
        }catch (Exception exp){
            this.finished = 2;
            this.errmsg = exp.getMessage();
            this.callback.failed(request, httpResult, exp);
        }
    }

    @Override
    public void failed(Exception exp) {
        this.finished = 2;
        this.errmsg = exp.getMessage();
        this.callback.failed(request, null, exp);
    }

    @Override
    public void cancelled() {
        finished = 3;
        this.callback.cancelled(request);
    }

    public void reset(){
        this.request = null;
        this.callback = null;
        this.errmsg = null;
        this.finished = 0;
    }

}